package com.moyoutian.line.link;

/**
 * 单向链表
 */
public class DoubleLinkList<D> {


    private Node header;

    private Node tail;


    public Node getHeader() {
        return header;
    }

    public void setHeader(Node header) {
        this.header = header;
    }

    public Node getTail() {
        return tail;
    }

    public void setTail(Node tail) {
        this.tail = tail;
    }

    public class Node {

        /**
         * 节点数据
         */
        private D data;
        /**
         * 下一个节点
         */
        private Node nextNode;


        /**
         * 前一个节点
         */
        private Node beforeNode;

        public Node() {
        }

        public Node(D data) {
            this.data = data;
        }
    }


    public DoubleLinkList() {
    }

    /**
     * @param headerData 头结点中的数据
     */
    public DoubleLinkList(D headerData) {
        this.header = new Node(headerData);
    }

    /**
     * 添加元素到尾部
     *
     * @param d 数据
     */
    public void addTail(D d) {
        if (tail == null) {
            header = new Node(d);
            tail = header;
        } else {
            tail.nextNode = new Node(d);
            tail.nextNode.beforeNode = tail;
            tail = tail.nextNode;
        }
    }

    /**
     * 添加元素到头部
     *
     * @param d 数据
     */
    public void addHeader(D d) {
        if (tail == null) {
            header = new Node(d);
            tail = header;
        } else {
            header.beforeNode = new Node(d);
            header.beforeNode.nextNode = header;
            header = header.beforeNode;
        }
    }


    public void remove(D data) {
        Node tempNode = header;
        if (header != null) {
            //删除非头结点
            while (tempNode != null) {
                // 找到当前结点
                if (tempNode.data == data) {
                    // 如果当前结点的前一个结点不为null，就将其下一个结点设置层当前结点的下个结点。
                    if (tempNode.beforeNode != null) {
                        tempNode.beforeNode.nextNode = tempNode.nextNode;
                    } else {
                        //如果为空证明到了头结点,重置头结点为下一个结点
                        header = tempNode.nextNode;
                    }
                    // 如果当前结点的后一个结点不为null，就将其下一个结点设置层当前结点的下个结点。
                    if (tempNode.nextNode != null) {
                        tempNode.nextNode.beforeNode = tempNode.beforeNode;
                    } else {
                        //证明需要换尾巴
                        tail = tempNode.beforeNode;
                    }
                    return;
                }
                tempNode = tempNode.nextNode;
            }
        }
    }


    public void toStr() {
        Node temp = header;
        while (temp != null) {
            System.out.println("D:" + temp.data);
            temp = temp.nextNode;
        }
    }


}
